package com.example.qqviewspringboot.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.firewall.HttpFirewall;
import org.springframework.security.web.firewall.StrictHttpFirewall;
import org.springframework.security.config.annotation.web.configuration.WebSecurityCustomizer;

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig {

    /**
     * 配置 Spring Security 的过滤链
     *
     * @param http HttpSecurity 对象
     * @return 配置好的 SecurityFilterChain
     * @throws Exception 可能抛出的异常
     */
    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http
                .csrf().disable() // 禁用 CSRF 保护，适用于 WebSocket 和 API 场景
                .authorizeRequests(authorizeRequests -> authorizeRequests
                        .antMatchers(
                                "/api/friendships/**",
                                "/api/messages/**",
                                "/api/**",
                                "/ws",
                                "/ws/**",
                                "/",
                                "/index.html",
                                "/css/**",
                                "/js/**",
                                "/images/**",
                                "/avatars/**",
                                "/uploads/**" // 允许匿名访问 uploads 目录
                        ).permitAll()
                        .anyRequest().authenticated() // 其他所有请求需要认证
                )
                .formLogin().disable() // 禁用表单登录
                .httpBasic(); // 启用 HTTP Basic 认证
        return http.build();
    }

    /**
     * 定义自定义的 HttpFirewall，以允许特定的 URL 编码字符
     *
     * @return 配置好的 HttpFirewall
     */
    @Bean
    public HttpFirewall allowCustomHttpFirewall() {
        StrictHttpFirewall firewall = new StrictHttpFirewall();
        firewall.setAllowUrlEncodedPercent(true); // 允许 URL 中包含 % 字符
        firewall.setAllowUrlEncodedSlash(true); // 允许 URL 中包含 /
        firewall.setAllowBackSlash(true); // 允许反斜杠
        firewall.setAllowSemicolon(true); // 允许分号
        firewall.setAllowUrlEncodedDoubleSlash(true); // 允许双斜杠
        firewall.setAllowUrlEncodedPeriod(true); // 允许编码的句号
        return firewall;
    }

    /**
     * 将自定义的 HttpFirewall 应用到 WebSecurity
     *
     * @param firewall 自定义的 HttpFirewall
     * @return 配置好的 WebSecurityCustomizer
     */
    @Bean
    public WebSecurityCustomizer webSecurityCustomizer(HttpFirewall firewall) {
        return (web) -> web.httpFirewall(firewall);
    }
}
